398D - Instant Messanger - CodeForces Solution


data structures

Please click on ads to support us..

C++ Code:

#include <bits/stdc++.h>
using namespace std;

// #include "debug.h"

using ll = long long;

#define set unordered_set

const int N = 50000+1;
const int M = 150000+1;
const int Q = 250000+1;
const int S = 550;
const int H = 550;
 
struct Query {
  char t;
  int u, v, idx, ans;
};
 
int n, m, qq;
bool online[N];
int maxedges[N];
bool heavy[N];
vector<int> hvy;
set<int> ofriends[N];
int lfriends[N];
set<int> pointing[N];
set<int> adj[N];
set<int> hadj[N];

void add_edge(int u, int v) {
  adj[u].insert(v);
  adj[v].insert(u);
  if (heavy[v]) hadj[u].insert(v);
  if (heavy[u]) hadj[v].insert(u);
}

void del_edge(int u, int v) {
  adj[u].erase(v);
  adj[v].erase(u);
  if (heavy[v]) hadj[u].erase(v);
  if (heavy[u]) hadj[v].erase(u);
}
 
void recompute() {
  for (int i = 0; i < n; ++i) {
    ofriends[i].clear(); 
    lfriends[i] = 0;
  }
  for (int i = 0; i < n; ++i) {
    if (online[i]) {
      for (int j : adj[i]) {
        if (heavy[i]) ofriends[j].insert(i);
        if (not heavy[i]) ++lfriends[j];
        if (heavy[i] and heavy[j]) pointing[i].insert(j);
      }
    }
  }
}

void update_heavy() {
  for (int i : hvy) {
    ofriends[i].clear();
  }
  for (int i : hvy) {
    if (online[i]) {
      for (int j : hadj[i]) {
        ofriends[j].insert(i);
      }
    }
  }
}

void apply(const Query& q) {
  if (q.t == 'O') {
    online[q.u] = true;
    if (not heavy[q.u]) {
      for (int j : adj[q.u]) {
        ++lfriends[j];
      }
    }
  }
  else if (q.t == 'F') {
    online[q.u] = false;
    if (not heavy[q.u]) {
      for (int j : adj[q.u]) {
        --lfriends[j];
      }
    }
  }
  else if (q.t == 'A') {
    add_edge(q.u, q.v);
    if (online[q.u] and not heavy[q.u]) {
      ++lfriends[q.v];
    }
    if (online[q.v] and not heavy[q.v]) {
      ++lfriends[q.u];
    }
  }
  else if (q.t == 'D') {
    del_edge(q.u, q.v);
    if (online[q.u] and not heavy[q.u]) {
      --lfriends[q.v];
    }
    if (online[q.v] and not heavy[q.v]) {
      --lfriends[q.u];
    }
  }
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
 
  cin >> n >> m >> qq;
  for (int i = 0; i < n; ++i) {
    adj[i] = set<int>();
    pointing[i] = set<int>();
    ofriends[i] = set<int>();
    hadj[i] = set<int>();
    adj[i].max_load_factor(0.5);
    pointing[i].max_load_factor(0.5);
    ofriends[i].max_load_factor(0.5);
    hadj[i].max_load_factor(0.5);
    online[i] = false;
    maxedges[i] = 0;
  }

  int o;
  cin >> o;
  for (int i = 0; i < o; ++i) {
    int x;
    cin >> x; --x;
    online[x] = true;
  }

  vector<pair<int,int>> initial_edges;

  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b; --a; --b;
    initial_edges.emplace_back(a, b);
    ++maxedges[a], ++maxedges[b];
  }
 
  vector<Query> qs(qq);
  for (int i = 0; i < qq; ++i) {
    Query& q = qs[i];
    q.idx = i;
    q.ans = -1;
    cin >> q.t >> q.u, --q.u;
    if (q.t == 'A' or q.t == 'D')
      cin >> q.v, --q.v;
    else
      q.v = -1;
    if (q.t == 'A')
      ++maxedges[q.u], ++maxedges[q.v];
  }

  for (int i = 0; i < n; ++i) {
    adj[i].reserve(maxedges[i]);
    ofriends[i].reserve(maxedges[i]);
    pointing[i].reserve(maxedges[i]);
    hadj[i].reserve(maxedges[i]);
    heavy[i] = (maxedges[i] >= H);
    if (heavy[i]) hvy.push_back(i);
  }

  for (auto e : initial_edges) {
    add_edge(e.first, e.second);
  }

  recompute();

  set<int> modified;
  modified.max_load_factor(0.5);
  modified.reserve(S);

  for (Query& q : qs) {
    if (modified.size() >= S) {
      recompute();
      modified.clear();
    }

    if (q.t == 'C') {
      // D(modified.size()) << endl;
      if (heavy[q.u]) {
        q.ans = lfriends[q.u] + (int)ofriends[q.u].size();
        for (int i : modified) {
          if (ofriends[q.u].count(i)) {
            if ((not online[i]) or (not adj[q.u].count(i)))
              --q.ans;
          }
          else {
            if (online[i] and adj[q.u].count(i))
              ++q.ans;
          }
        }
      }
      else {
        q.ans = lfriends[q.u];
        for (int i : hadj[q.u]) {
          if (online[i]) ++q.ans;
        }
      }
      cout << q.ans << '\n';
    }
    else {
      apply(q);
      if (heavy[q.u]) modified.insert(q.u);
      if (q.v != -1 and heavy[q.v]) modified.insert(q.v);
    }
  }
}


Comments

Submit
0 Comments
More Questions

1279A - New Year Garland
1279B - Verse For Santa
202A - LLPS
978A - Remove Duplicates
1304A - Two Rabbits
225A - Dice Tower
1660D - Maximum Product Strikes Back
1513A - Array and Peaks
1251B - Binary Palindromes
768B - Code For 1
363B - Fence
991B - Getting an A
246A - Buggy Sorting
884A - Book Reading
1180A - Alex and a Rhombus
445A - DZY Loves Chessboard
1372A - Omkar and Completion
159D - Palindrome pairs
981B - Businessmen Problems
1668A - Direction Change
1667B - Optimal Partition
1668B - Social Distance
88B - Keyboard
580B - Kefa and Company
960A - Check the string
1220A - Cards
897A - Scarborough Fair
1433B - Yet Another Bookshelf
1283B - Candies Division
1451B - Non-Substring Subsequence